﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;

public class Player : Characters
{
    private NPC nextfromNPC;
    private Interaction nextfromObj;
    private bool isnext = false;
    private Texture2D exclamation;
    private List<Condition> condition;
    private bool finished;
    private Texture2D finishedDay, postit, postit2, dark;

    private bool showingHUD = true;

    private string name;
    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    private List<Item> itemList;
    public List<Item> ItemList
    {
        get { return itemList; }
    }
    
    public enum PlayerNumber { ONE, TWO }

    private int intCount;

    private bool itemChange = false;

    public NPC NextFrom
    {
        get { return nextfromNPC; }
        set { nextfromNPC = value; }
    }

    public Interaction NextFromObj
    {
        get { return nextfromObj; }
        set { nextfromObj = value; }
    }

    public bool IsNext
    {
        get { return isnext;  }
        set 
        {
            if (!isnext && value)
            {
                AudioManager.PlaySound("Audio/sfx_menuMove");
            }
            isnext = value; 
        }
    }

    public Player.PlayerNumber player;

    private int carisma;
    private int percepcao;
    private int inteligencia;

    public List<Condition> Condition
    {
        get { return condition; }
    }

    public int Inteligencia
    {
        get 
        {
            if (equiped) return inteligencia + item.InteligenciaBonus;
            else return inteligencia;
        }
        set { inteligencia = value; }
    }

    public int Percepcao
    {
        get
        {
            if (equiped) return percepcao + item.PercepcaoBonus;
            else return percepcao;
        }
        set { percepcao = value; }
    }

    public int Carisma
    {
        get
        {
            if (equiped) return carisma + item.CarismaBonus;
            else return carisma;
        }
        set { carisma = value; }
    }

    Item item;
    private bool equiped = false;

    Color[] personTextureData;
    public Color[] PersonTextureData
    {
        get { return personTextureData; }
    }

    public Player(Player.PlayerNumber player, float speed, float friction, Vector2 position)
        : base(speed, friction, position)
    {
        Life = 5;
        this.player = player;
        LoadContent(GameSession.Content);

        carisma = 5; percepcao = 5; inteligencia = 5;

        itemList = new List<Item>();
        condition = new List<Condition>();
    }


    /// <summary>
    /// Handles input, performs physics, and animates the player sprite.
    /// </summary>
    public override void Update(GameTime gameTime)
    {
        GetInput();
        Vector2 vel = Velocity;

        Vector2 pos = Position;

        pos += new Vector2(Velocity.X, 0);

        int left = (int)Math.Round(pos.X - sprite.Origin.X) + localBounds.X;
        int top = (int)Math.Round(pos.Y - sprite.Origin.Y) + localBounds.Y;

        Rectangle bound = new Rectangle(left, top, localBounds.Width, localBounds.Height);

        Console.WriteLine("em x " + position.X + " " + position.Y);

        if (GameSession.CheckCollision(bound))
        {
            Velocity.X = 0;
            Console.WriteLine("colidiu em x");
        }


        pos = Position;
        pos += new Vector2(0, Velocity.Y);

        left = (int)Math.Round(pos.X - sprite.Origin.X) + localBounds.X;
        top = (int)Math.Round(pos.Y - sprite.Origin.Y) + localBounds.Y;

        bound = new Rectangle(left, top, localBounds.Width, localBounds.Height);

        Console.WriteLine("em y " + left + " " + top);

        if (GameSession.CheckCollision(bound))
        {
            Velocity.Y = 0;
            Console.WriteLine("colidiu em y");
        }

        base.Update(gameTime);
    }

    public virtual void LoadContent(ContentManager content) 
    {
        // Load animated textures.

        Texture2D chara = content.Load<Texture2D>("Textures/Characters/charjogador");

        CreateAnimation(chara);

        exclamation = content.Load<Texture2D>("Textures/Characters/Lampada");
        finishedDay = content.Load<Texture2D>("Textures/aprovado");
        dark = content.Load<Texture2D>("Textures/dark");
        postit = content.Load<Texture2D>("Textures/Screen/postit3");
        postit2 = content.Load<Texture2D>("Textures/Screen/postit4");
        
        // Calculate bounds within texture size.            
        /*int width = (int)(idleDownAnimation.FrameWidth * Globals.CollisionWidth);
        int left = (idle DownAnimation.FrameWidth - width) >> 1;
        int height = (int)(idleDownAnimation.FrameWidth * Globals.CollisionHeight) >> 1;
        int top = (idleDownAnimation.FrameHeight - height);
        localBounds = new Rectangle(left, top, width, height);*/

        //Avoiding crashes on differents CPU's.
        //sprite.PlayAnimation(idleDownAnimation);

        personTextureData = new Color[BoundingRectangle.Width * BoundingRectangle.Height];

        for (int i = 0; i < personTextureData.Length; i++)
            personTextureData[i] = Color.Black;
    }

    protected override void ApplyPhysics(bool checkall)
    {
        Vector2 previousPosition = Position;

        Rectangle previousBounding = BoundingRectangle;

        base.ApplyPhysics(/*gameTime*/ checkall);

        //handle collision

        /*if (Position.X == previousPosition.X)
            Velocity.X = 0;

        if (Position.Y == previousPosition.Y)
            Velocity.Y = 0;*/

    }

    /// <summary>
    /// Gets player movement and commands from input.
    /// </summary>
    protected void GetInput()
    {
        float speed = Speed;

        if (player == PlayerNumber.ONE)
        {
          
            //if (!finished)
            {
                intCount++;
                if (intCount > 10)
                {
                    if (finished && InputManager.IsActionTriggered())
                    {
                        finished = false;
                        GameSession.DayCompleted();

                        _Direction = Direction.Down;
                        return;
                    }
                    else
                    if (InputManager.IsActionTriggered(InputManager.Action.Space))
                    {
                        intCount = 0;
                        if (isnext)
                        {
                            AudioManager.PlaySound("Audio/sfx_menuSelect");
                            if (nextfromNPC != null)
                            {
                                Thought thought = GetThought(nextfromNPC.ThoughtList);
                                if (thought != null && !thought.Sentence.Equals(string.Empty))
                                    GameSession.ScreenManager.AddScreen(new ThoughtScreen(thought, Interact.DIALOG));
                                else
                                    StartDialog();
                            }
                            else
                                if (nextfromObj != null)
                                {
                                    Thought thought = GetThought(nextfromObj.ThoughtList);
                                    if (thought != null && !thought.Sentence.Equals(string.Empty))
                                        GameSession.ScreenManager.AddScreen(new ThoughtScreen(thought, Interact.INTERACTION));
                                    else
                                        StartInteraction();
                                    //nextfromNPC = null;
                                }
                        }
                    }
                    else
                    if (InputManager.IsActionPressed(InputManager.Action.ShowHUD) && !finished)
                    {
                        intCount = 0;

                        showingHUD = !showingHUD;
                    }
                }
                if (InputManager.IsActionPressed(InputManager.Action.MovePlayer1Down) && !finished)
                {
                    Velocity.Y += speed;
                    _Direction = Direction.Down;
                }
                if (InputManager.IsActionPressed(InputManager.Action.MovePlayer1Up) && !finished)
                {
                    Velocity.Y -= speed;
                    _Direction = Direction.Up;
                }
                if (InputManager.IsActionPressed(InputManager.Action.MovePlayer1Right) && !finished)
                {
                    Velocity.X += speed;
                    _Direction = Direction.Right;
                }
                if (InputManager.IsActionPressed(InputManager.Action.MovePlayer1Left) && !finished)
                {
                    Velocity.X -= speed;
                    _Direction = Direction.Left;
                }

            }
            
            
        }
        else
        {
            if (InputManager.IsActionPressed(InputManager.Action.MovePlayer2Down))
            {
                Velocity.Y += Speed;
                _Direction = Direction.Down;
                //ApplyPhysics(/*gameTime*/ true);
            }
            if (InputManager.IsActionPressed(InputManager.Action.MovePlayer2Up))
            {

                Velocity.Y -= Speed;
                _Direction = Direction.Up;

                //ApplyPhysics(/*gameTime*/ true);
            }
            if (InputManager.IsActionPressed(InputManager.Action.MovePlayer2Right))
            {
                Velocity.X += Speed;
                _Direction = Direction.Right;
                //ApplyPhysics(/*gameTime*/ true);
            }
            if (InputManager.IsActionPressed(InputManager.Action.MovePlayer2Left))
            {
                Velocity.X -= Speed;
                _Direction = Direction.Left;
                //ApplyPhysics(/*gameTime*/ true);
            }
        }

        //ApplyPhysics(/*gameTime*/ true);
    }

    int thoughtNum;
    public Thought GetThought(List<Thought> thoughtList)
    {
        thoughtNum = -1;
        for (int i = thoughtList.Count - 1; i >= 0; i--)
        {
            if (GameSession.CheckAllConditions(thoughtList[i].Need))
            {
                thoughtNum = i;
                return thoughtList[i];
            }
        }

        return null;
    }

    public void StartDialog()
    {
        if (thoughtNum >= 0)
            GameSession.GiveCondition(nextfromNPC.ThoughtList[thoughtNum].Give);

        if (nextfromNPC.Dialogos != null && nextfromNPC.Dialogos.Count > 0 && nextfromNPC.HasDialog)
            GameSession.ScreenManager.AddScreen(new DialogScreen(nextfromNPC));
    }

    public void StartInteraction()
    {
        if(thoughtNum>=0)
            GameSession.GiveCondition(nextfromObj.ThoughtList[thoughtNum].Give);

        if (nextfromObj.Teleporte.Length > 0)
        {
            GameSession.LoadMap(nextfromObj.Teleporte[0]);
            Position = new Vector2(nextfromObj.Teleporte[1] * 64, nextfromObj.Teleporte[2] * 64);
        }
        else
            if(nextfromObj.ObjList.Count > 0 || !nextfromObj.ShowTextSpace)
                GameSession.ScreenManager.AddScreen(new ObjectInteractionScreen(nextfromObj));
    }

    private void Desequip(Item item)
    {
        item = null;
    }

    private void Equip(Item item)
    {
        this.item = item;
    }

    int countchange = 0;
    int countchange2 = 0;
    bool aux = true;

    public void DrawHUD(GameTime gameTime, SpriteBatch spriteBatch)
    {
        if (!showingHUD)
        {
            spriteBatch.Draw(postit2, new Vector2(10, 10), Color.White);

            spriteBatch.DrawString(Globals.Font, name, new Vector2(50, 40), Color.Black);

            return;
        }

        Color color = Color.Black;

        spriteBatch.Draw(postit, new Vector2(10, 10), Color.White);

        spriteBatch.DrawString(Globals.Font, name, new Vector2(50, 40), color);

        spriteBatch.DrawString(Globals.Font, "Objetivos: " + GameSession.GetObjetives(), new Vector2(50, 90), color);

        spriteBatch.DrawString(Globals.Font, "Atributos ", new Vector2(50, 130), color);

        if (!equiped)
        {
            spriteBatch.DrawString(Globals.Font, "Carisma: " + carisma, new Vector2(70, 170), color);
            spriteBatch.DrawString(Globals.Font, "Inteligencia: " + inteligencia, new Vector2(70, 190), color);
            spriteBatch.DrawString(Globals.Font, "Percepcao: " + percepcao, new Vector2(70, 210), color);
        }
        else
        {
            spriteBatch.DrawString(Globals.Font, "Carisma: " + carisma + " + " + item.CarismaBonus + " = " + (carisma + item.CarismaBonus), new Vector2(70, 170), color);
            spriteBatch.DrawString(Globals.Font, "Inteligencia: " + inteligencia + " + " + item.InteligenciaBonus + " = " + (carisma + item.InteligenciaBonus), new Vector2(70, 190), color);
            spriteBatch.DrawString(Globals.Font, "Percepcao: " + percepcao + " + " + item.PercepcaoBonus + " = " + (carisma + item.PercepcaoBonus), new Vector2(70, 210), color);
        }

        spriteBatch.DrawString(Globals.Font, "Itens:", new Vector2(50, 260), color);

        int x = 0;
        //foreach (Item item in itemList)
        int min = itemList.Count - 3;
        if(min < 0 ) min = 0;
        for (int min2 = min; min2 < itemList.Count; min2++ )
        {
            item = itemList[min2];

            if (itemChange && aux)
                spriteBatch.DrawString(Globals.Font, item.Name + " -> " + item.Quantidade, new Vector2(70, 300 + x), Color.Red);
            else
                spriteBatch.DrawString(Globals.Font, item.Name + " -> " + item.Quantidade, new Vector2(70, 300 + x), color);

            if (itemChange)
            {
                countchange++;
                if (countchange == 15)
                {
                    countchange2++;
                    countchange = 0;
                    aux = !aux;
                }
                if (countchange2 == 20)
                {
                    countchange = 0;
                    countchange2 = 0;
                    aux = true;
                    itemChange = false;
                }
            }

            x += 20;
        }

    }

    public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
    {
        if (isnext)
            spriteBatch.Draw(exclamation, new Vector2(Globals.ScreenWidth2 - 20, Globals.ScreenHeight2 - 150), Color.White);

        sprite.Draw(gameTime, spriteBatch, new Vector2(Globals.ScreenWidth2, Globals.ScreenHeight2), SpriteEffects.None); 
        //base.Draw(gameTime, spriteBatch);

        if (finished)
        {
            spriteBatch.Draw(dark, Vector2.Zero, Color.White);
            //Globals.IsPaused = true;
            spriteBatch.Draw(finishedDay, new Vector2(Globals.ScreenWidth2 - finishedDay.Width / 2, Globals.ScreenHeight2 - finishedDay.Height / 2), Color.White);
        }
    }

    public void ReceiveCondition(Condition received)
    {
        if (received == null)
            return;

        if (received.Kind == ConditionKind.ATRIBUTE)
            return;

        if (received.Kind == ConditionKind.ITEM)
        {
            Item item = HasItem(received.ID);

            if(item != null)
            {
                item.Quantidade += received.Quantidade;
                itemChange = true;
                return;
            }

            itemList.Add(new Item(received.ID, received.Quantidade));
            itemChange = true;
            return;
        }

        /*
        if (received.ID.Equals("contrato"))
        {
            itemList.Add(new Item("Contrato"));
            itemChange = true;
        }
        else
            if (received.ID.Equals("assinatura de contrato") && itemList[0].Name.Equals("Contrato"))
            {
                itemList[0].Name = "Contrato com 1 assinatura";
                itemChange = true;
            }
            else
                if (received.ID.Equals("contrato assinado") && itemList[0].Name.Equals("Contrato com 1 assinatura"))
                {
                    itemList[0].Name = "Contrato com 2 assinaturas";
                    itemChange = true;
                }*/

        condition.Add(received);

        if (received.ID.Equals("fim do dia"))
        {
            finished = true;
            itemList.Clear();
            condition.Clear();
        }

        //Console.WriteLine("condiçao ok: " + received.ID);

    }

    private Item HasItem(String itemToCheck)
    {
        foreach(Item item in itemList)
        {
            if (item.Name.Equals(itemToCheck))
            {
                return item;
            }
        }

        return null;
    }

    internal void RemoveCondition(Condition condition)
    {
        if (condition.Kind == ConditionKind.ITEM)
        {
            for (int i = itemList.Count - 1; i >= 0; i--)
            {
                Item item = itemList[i] ;
                if (item.Name.Equals(condition.ID))
                {
                    itemList[i].Quantidade -= condition.Quantidade;
                    if (itemList[i].Quantidade <= 0)
                    {
                        itemList.RemoveAt(i);
                        break;
                    }
                    itemChange = true;
                }
            }
        }
        else
        {
            if (condition.Kind == ConditionKind.LICENSE)
            {
                List<Condition> cond = new List<Condition>();
                cond.Add(condition);
                if(GameSession.CheckAllConditions(cond))
                {
                    //this.condition.Remove(condition);
                    for (int i = this.condition.Count - 1; i >= 0; i--)
                    {
                        if (this.condition[i].ID.Equals(condition.ID))
                        {
                            this.condition.RemoveAt(i);
                            break;
                        }
                    }
                }
            }
        }
    }
}